Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Функция автоматической замены (SDEVIL)
Author Message
SDEVIL
Guest





Карма: 388
   поощрить/наказать


PostPosted: Fri Jul 27, 2007 2:56 pm (написано за 1 минуту 7 секунд)
   Post subject: Функция автоматической замены
Reply with quote

Такая задача: есть текст, текст берется из формы которую заполняет пользователь, при этом html тэги разрешены, необходимо найти в тексте ссылки на сайты(пример: www.site.ru || site.ru || site.ru и т.д.) которые написаны просто как текст(по которым нельзя щелкнуть для перехода), и сделать их полноценными ссылками (пример: <a href="www.site.ru">www.site.ru</a>) т.е. сделать автозамену, но при этом в тексте так же могут присутствовать и нормальные ссылки (пример: <a href="www.site.ru">www.site.ru</a>) - их нельзя трогать они должны остаться как есть.
Так же работает и с e-mailами т.е. при нажатии на замененную ссылку открывается почтовая программа...
Вот сам код:
Code (php): скопировать код в буфер обмена
class LinkHandling
{
   private static (www.php.net/static) $isA = false;
   const patten = "#(?(?=</?\w+)<(/?\w+)\s?[^>]*>|(?:www\.|[a-z\d][a-z\d.\-_]*(@)|(?:http|ftp)s?://)[a-z\d]+(?:\.[a-z\d]+)*(/[a-z\d+\-_\.,%&/?=\#\[\]*!~']*)?)#";
   public static (www.php.net/static) function Run($str)
   {
      self::$isA = false;
      return preg_replace_callback (www.php.net/preg_replace_callback)(self::patten, array (www.php.net/array)("self", "Replace"), $str);
   }
   public static (www.php.net/static) function Replace($m)
   {
      if (!empty (www.php.net/empty)($m[1]))
      {
         if ($m[1] == "a") self::$isA = true;
         else if ($m[1] == "/a") self::$isA = false;
         return $m[0];
      }
      else if (self::$isA) return $m[0];
      return "<a href=\"".(isset (www.php.net/isset)($m[2]) && $m[2] == "@" ? "mailto:{$m[0]}" : $m[0] )."\">{$m[0]}</a>";
   }
}
Только заметил такую штуку, если в тексте написано: www.site.ru то получается <a href="www.site.ru">www.site.ru</a> и такая ссылка не работает, а если написано www.site.ru то тогда все работает, как можно это исправить?
Back to top
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Fri Jul 27, 2007 4:54 pm (спустя 1 час 57 минут; написано за 6 минут 7 секунд)
   Post subject:
Reply with quote

SDEVIL, А еще есть сайты которым не нравится добавление www перед именем домена. таких не очень много, но они есть. Кроме того многим сайтам пофиг есть или нет www перед именем домена. Так что по-хорошему надо еще сайт долбить на пример того рабочая ссылка или нет, чтобы не плодить дохлые линки.
ИМХО логика должна быть такая:
1. Выделили чистый домен начиная со 2-го уровня. Проверили, что резолвится dns.
2. Пошли проверять дальше по уровням домена.
3. Дошли до верха, сделали запрос по http. Если получили ответ - слелали линк и успокоились.
4. Если нет и последний уровень не www, то добавили www и попробывали с ним. Если не вышло, то ссылка в мусор.
Back to top
View user's profile Send private message
Anarki
Заглянувший



Joined: 20 Aug 2005
Posts: 5
Карма: 2
   поощрить/наказать


PostPosted: Fri Jul 27, 2007 10:59 pm (спустя 6 часов 5 минут; написано за 20 секунд)
   Post subject:
Reply with quote

Если я правильно понял, то
Code (php): скопировать код в буфер обмена
class LinkHandling
{
   private static (www.php.net/static) $isA = false;
   const patten = "#(?(?=</?\w+)<(/?\w+)\s?[^>]*>|(?:www\.|[a-z\d][a-z\d.\-_]*(@)|(?:http|ftp)s?://)[a-z\d]+(?:\.[a-z\d]+)*(/[a-z\d+\-_\.,%&/?=\#\[\]*!~']*)?)#";
   public static (www.php.net/static) function Run($str)
   {
      self::$isA = false;
      return preg_replace_callback (www.php.net/preg_replace_callback)(self::patten, array (www.php.net/array)("self", "Replace"), $str);
   }
   public static (www.php.net/static) function Replace($m)
   {
      if (!empty (www.php.net/empty)($m[1]))
      {
         if ($m[1] == "a") self::$isA = true;
         else if ($m[1] == "/a") self::$isA = false;
         return $m[0];
      }
      else if (self::$isA) return $m[0];
      return "<a href=\"".(isset (www.php.net/isset)($m[2]) && $m[2] == "@" ? "mailto:{$m[0]}" : (strpos (www.php.net/strpos)(strtolower (www.php.net/strtolower)($m[0]),'http://') !== 0) ? 'http://'.$m[0] : $m[0] )."\">{$m[0]}</a>";
   }
}
Изменилась строчка с return
Back to top
View user's profile Send private message
Guest






Карма: 388
   поощрить/наказать


PostPosted: Sat Jul 28, 2007 1:13 am (спустя 2 часа 13 минут; написано за 2 минуты 50 секунд)
   Post subject:
Reply with quote

Anarki wrote:
Если я правильно понял, то
Изменилась строчка с return
Работать стало, но теперь перестало работать с емайлом т.е. если написано <a href='mailto:mail@mail.ru'>mail@mail.ru</a> - то скрипт не трогает строку, а если написано mail@mail.ru - то получается ссылка вот такого вида - <a href='mail@mail.ru'>mail@mail.ru</a>
вместо <a href='mailto:mail@mail.ru'>mail@mail.ru</a>
Back to top
Михаил Саяпин
Участник форума



Joined: 07 Apr 2007
Posts: 46
Карма: 15
   поощрить/наказать

Location: Санкт-Петербург

PostPosted: Sat Jul 28, 2007 10:51 am (спустя 9 часов 38 минут; написано за 5 минут 23 секунды)
   Post subject:
Reply with quote

Здравствуйте,

Если вам действительно нужна серьезная схема замены адресов, то, я боюсь, дело должно закончиться разделением строки по пробельным символам, проверке каждого слова на потенциальность URL (например, вхождения в нее ".(все|возможные|tld) (data.iana.org/TLD/tlds-alpha-by-domain.txt)") или же e-mail (вхождением @). Дальнейшая валидация должна включать отделение доменного имени от URL и проверки по checkdnsrr (www.php.net/manual/en/function.checkdnsrr.php)(), его же отделение от @ в e-mail, валидацию по RFC 2822 (www.faqs.org/rfcs/rfc2822.html) самого адреса... Кроме того, наряду с http:// существует еще некоторое количество протоколов, которым тоже стоит уделить внимание - это ftp://, ftps://, https://... :) Поэтому мое мнение - зачем? Лучше возложить это торжественное дело на плечи людей, пишущих сообщение. И ошибок будет меньше, и адреса - там, где они реально нужны с точки зрения пользователя.
Back to top
View user's profile Send private message
Антон Макаренко
Участник форума



Joined: 05 Feb 2004
Posts: 374
Карма: 37
   поощрить/наказать

Location: Киев

PostPosted: Mon Jul 30, 2007 9:53 am (спустя 1 день 23 часа 2 минуты; написано за 44 секунды)
   Post subject:
Reply with quote

SDEVIL
Попробуйте такое готовое решение: forum.dklab.ru/php/advises/PodsvechivanieHttpReferencesInTheText.html
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML